library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.1     ✔ stringr   1.5.2
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(knitr)
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(plotly)
## 
## Attaching package: 'plotly'
## 
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following object is masked from 'package:graphics':
## 
##     layout
# Source helper functions
source("../scripts/02_data_processing.R")

# Load all data
data <- load_all_data()

# Color palette
hawaii_colors <- c(
  ocean = "#006BA6",
  lava = "#C1121F",
  forest = "#2D6A4F",
  sand = "#F4A261",
  sunset = "#E76F51",
  sky = "#219EBC"
)

Overview

Hawaii’s Big Island

  • Largest Hawaiian Island
  • 4,028 square miles
  • 206,400 residents (2023)
  • Active volcanic zones
  • Diverse microclimates

Analysis Focus

  1. Demographics
  2. Climate
  3. Economics
  4. Natural Disasters

Executive Summary

  • Population: Growing 4.9% since 2015, but aging rapidly
  • Economy: Tourism-dependent with $70,200 median income
  • Climate: Warming trends, extreme heat days tripled
  • Hazards: $800M in volcanic damage (2018), ongoing tsunami risk

Demographics

Population Growth

p <- ggplot(data$demographics, aes(x = year, y = population)) +
  geom_line(color = hawaii_colors["ocean"], size = 2) +
  geom_point(color = hawaii_colors["ocean"], size = 4) +
  scale_y_continuous(labels = comma, limits = c(190000, 210000)) +
  labs(
    title = "Steady Population Growth",
    subtitle = "196,823 (2015) → 206,400 (2023)",
    x = NULL,
    y = "Population"
  ) +
  theme_minimal(base_size = 16) +
  theme(plot.title = element_text(face = "bold", size = 20))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggplotly(p) %>%
  layout(hovermode = "x unified")

Aging Population

aging_data <- data$demographics %>%
  select(year, percent_65_over, percent_under_18) %>%
  pivot_longer(cols = c(percent_65_over, percent_under_18),
               names_to = "group", values_to = "percentage") %>%
  mutate(group = ifelse(group == "percent_65_over", "65 and Over", "Under 18"))

ggplot(aging_data, aes(x = year, y = percentage, color = group)) +
  geom_line(size = 1.5) +
  geom_point(size = 3) +
  scale_color_manual(values = c("65 and Over" = hawaii_colors["lava"],
                                 "Under 18" = hawaii_colors["ocean"])) +
  labs(
    title = "Age Distribution Shift",
    x = NULL,
    y = "Percentage",
    color = "Age Group"
  ) +
  theme_minimal(base_size = 14) +
  theme(legend.position = "bottom")
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's colour values.
## No shared levels found between `names(values)` of the manual scale and the
## data's colour values.
## No shared levels found between `names(values)` of the manual scale and the
## data's colour values.

Implications

  • Healthcare demands ↑
  • School enrollment ↓
  • Workforce challenges

Cultural Diversity

ggplot(data$race_composition, aes(x = reorder(category, percentage), y = percentage)) +
  geom_col(fill = hawaii_colors["sunset"], width = 0.7) +
  geom_text(aes(label = paste0(percentage, "%")),
            hjust = -0.2, size = 6, fontface = "bold") +
  coord_flip() +
  scale_y_continuous(limits = c(0, 40), expand = c(0, 0)) +
  labs(
    title = "No Single Majority - Truly Multicultural",
    x = NULL,
    y = "Percentage of Population"
  ) +
  theme_minimal(base_size = 16) +
  theme(plot.title = element_text(face = "bold", size = 18))

Climate

Monthly Patterns

climate_data <- data$climate_monthly %>%
  mutate(month = factor(month, levels = month.name))

ggplot(climate_data) +
  geom_col(aes(x = month, y = avg_precip_in),
           fill = hawaii_colors["ocean"], alpha = 0.6, width = 0.7) +
  geom_line(aes(x = month, y = avg_temp_f / 5, group = 1),
            color = hawaii_colors["lava"], size = 1.5) +
  geom_point(aes(x = month, y = avg_temp_f / 5),
             color = hawaii_colors["lava"], size = 4) +
  scale_y_continuous(
    name = "Precipitation (inches)",
    sec.axis = sec_axis(~ . * 5, name = "Temperature (°F)")
  ) +
  labs(
    title = "Hilo Climate: Stable Temperature, Variable Rainfall",
    x = NULL
  ) +
  theme_minimal(base_size = 14) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    plot.title = element_text(face = "bold", size = 17),
    axis.title.y.left = element_text(color = hawaii_colors["ocean"], size = 14),
    axis.title.y.right = element_text(color = hawaii_colors["lava"], size = 14)
  )

Climate Change Signals

ggplot(data$climate_annual, aes(x = year)) +
  geom_line(aes(y = avg_temp_f), color = hawaii_colors["lava"], size = 1.8) +
  geom_point(aes(y = avg_temp_f), color = hawaii_colors["lava"], size = 4) +
  geom_col(aes(y = extreme_heat_days / 2 + 70),
           fill = hawaii_colors["sunset"], alpha = 0.5) +
  scale_y_continuous(
    name = "Average Temperature (°F)",
    sec.axis = sec_axis(~ (. - 70) * 2, name = "Extreme Heat Days")
  ) +
  labs(
    title = "Warming Trend: Extreme Heat Days Tripled",
    subtitle = "12 days (2015) → 38 days (2023)",
    x = "Year"
  ) +
  theme_minimal(base_size = 14) +
  theme(plot.title = element_text(face = "bold", size = 18))

Temperature increased 2.3°F from 2015 to 2023. Extreme heat days (above 90°F) more than tripled.

Economics

Income Growth

p2 <- ggplot(data$economics, aes(x = year, y = median_income)) +
  geom_line(color = hawaii_colors["forest"], size = 2) +
  geom_point(color = hawaii_colors["forest"], size = 4) +
  scale_y_continuous(labels = dollar, limits = c(50000, 75000)) +
  labs(
    title = "Median Income: 29.5% Growth",
    subtitle = "$54,200 → $70,200",
    x = NULL,
    y = "Median Household Income"
  ) +
  theme_minimal(base_size = 16) +
  theme(plot.title = element_text(face = "bold", size = 20))

ggplotly(p2) %>%
  layout(hovermode = "x unified")

Unemployment Recovery

ggplot(data$economics, aes(x = year, y = unemployment_rate)) +
  geom_area(fill = hawaii_colors["lava"], alpha = 0.3) +
  geom_line(color = hawaii_colors["lava"], size = 2) +
  geom_point(color = hawaii_colors["lava"], size = 4) +
  geom_hline(yintercept = 4.0, linetype = "dashed", color = "gray30", size = 1) +
  annotate("rect", xmin = 2019.5, xmax = 2020.5, ymin = 0, ymax = 10,
           alpha = 0.15, fill = "red") +
  annotate("text", x = 2020, y = 9.5, label = "COVID-19",
           size = 6, fontface = "bold") +
  scale_y_continuous(labels = percent_format(scale = 1), limits = c(0, 10)) +
  labs(
    title = "Unemployment: COVID Spike, Strong Recovery",
    x = "Year",
    y = "Unemployment Rate (%)"
  ) +
  theme_minimal(base_size = 16) +
  theme(plot.title = element_text(face = "bold", size = 19))

Industry Breakdown

industry_plot <- data$industry_composition %>%
  arrange(desc(employment_share)) %>%
  slice(1:5)

ggplot(industry_plot, aes(x = reorder(sector, employment_share),
                          y = employment_share)) +
  geom_col(fill = hawaii_colors["ocean"], width = 0.7) +
  geom_text(aes(label = paste0(employment_share, "%")),
            hjust = -0.2, size = 5, fontface = "bold") +
  coord_flip() +
  scale_y_continuous(limits = c(0, 35)) +
  labs(
    title = "Top 5 Sectors",
    x = NULL,
    y = "Employment Share (%)"
  ) +
  theme_minimal(base_size = 14) +
  theme(plot.title = element_text(face = "bold"))

Tourism Dominance

  • 28.5% of jobs
  • Average wage: $42,000
  • Vulnerability to external shocks

Higher-Paying Sectors

  • Healthcare: $62,000
  • Government: $58,000
  • Construction: $52,000

Natural Disasters

Disaster Impact

ggplot(data$disasters, aes(x = year, y = damage_millions, fill = type)) +
  geom_col() +
  scale_y_continuous(labels = dollar_format(suffix = "M"), limits = c(0, 850)) +
  scale_fill_brewer(palette = "Set1") +
  labs(
    title = "Economic Impact of Natural Disasters",
    subtitle = "2018 Kilauea Eruption: $800M damage, 2,500 evacuations",
    x = "Year",
    y = "Damage (Millions USD)",
    fill = "Disaster Type"
  ) +
  theme_minimal(base_size = 15) +
  theme(
    legend.position = "bottom",
    plot.title = element_text(face = "bold", size = 18)
  )
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_col()`).

Volcanic Activity

ggplot(data$volcanic_activity, aes(x = year)) +
  geom_col(aes(y = eruption_days), fill = hawaii_colors["lava"], alpha = 0.7) +
  geom_line(aes(y = earthquakes_m3plus / 5),
            color = hawaii_colors["ocean"], size = 1.5) +
  geom_point(aes(y = earthquakes_m3plus / 5),
             color = hawaii_colors["ocean"], size = 4) +
  scale_y_continuous(
    name = "Eruption Days per Year",
    sec.axis = sec_axis(~ . * 5, name = "Earthquakes (M3+)")
  ) +
  labs(
    title = "Kilauea Activity: Eruptions and Seismic Events",
    x = "Year"
  ) +
  theme_minimal(base_size = 15) +
  theme(plot.title = element_text(face = "bold", size = 17))

2018 saw peak activity with 214 eruption days and 2,345 earthquakes M3+

Tsunami Risk

Population at Risk

Zone Population
Evacuation Zone 12,000
High Risk 35,000
Medium Risk 58,000
Low Risk 101,400

Total High/Evac: 47,000 (23% of population)

Risk Factors

  • Pacific Ring of Fire
  • Low-lying coastal areas
  • Limited evacuation routes
  • 24/7 warning system active

Recent Events

  • 2011: Japan tsunami
  • Regular warning drills
  • Updated evacuation maps

Key Findings

Synthesis

Demographic Challenge - Aging population (21% seniors) → healthcare pressures - Declining youth population → workforce concerns

Economic Vulnerability - Tourism dependence (28.5%) → shock sensitivity - Strong recovery post-COVID → resilience

Climate Concerns - Clear warming trend (+2.3°F) - Extreme heat days tripled → adaptation needed

Persistent Hazards - Active volcanoes ($800M+ damages) - 47,000 in tsunami risk zones

Strategic Priorities

Short Term

  1. Disaster preparedness
  2. Climate adaptation
  3. Tourism recovery support
  4. Healthcare capacity

Long Term

  1. Economic diversification
  2. Sustainable development
  3. Infrastructure resilience
  4. Demographic planning

Conclusions

Hawaii’s Big Island stands at a crossroads


Strengths

  • Economic recovery
  • Cultural diversity
  • Natural beauty
  • Tourism appeal

Challenges

  • Climate change
  • Natural hazards
  • Aging population
  • Economic concentration


Sustainable planning is essential for the island’s future prosperity and resilience

Questions?



Phoenix Stout

MA615 Final Project

December 15, 2025

GitHub Repository